import backtrader as bt

from indicators.KDJ import KDJ
from indicators.wave_index_ind import wave_index_ind
import backtrader.indicators as btind

class  TailPlateStrategy(bt.Strategy):
    # 策略参数
    params = dict(
        period=20,  # 均线周期
        look_back_days=30,
        printlog=False,
        period_ema_fast=10,
        period_ema_slow=100,
        short_window=30,
        long_window=60,
        N1=3,
        N2=50,
        N3=25,
        wave_window=20,
        wave_two_window=50,
        wave_three_window=70,
    )


    def __init__(self):

        for data in self.datas:
            data.loss = 0
            data.mas = dict()
            data.wave = wave_index_ind(wave_window=self.p.wave_window, data=data.close, subplot=False)

            # 五日移动平均线
            data.sma30 = bt.indicators.SimpleMovingAverage(data, period=30)
            data.sma3 = bt.indicators.SimpleMovingAverage(data, period=3)
            data.sma2 = bt.indicators.SimpleMovingAverage(data, period=2)
            data.K = KDJ().lines.K
            data.D = KDJ().lines.D
            data.J = KDJ().lines.J
            data.rsi= btind.RSI_Safe(data)

            #data.rsi = bt.indicators.RelativeStrengthIndex()


        # 遍历所有股票,计算20日均线
        # for data in self.datas:

    def notify_order(self, order):
        """
        订单状态处理

        Arguments:
            order {object} -- 订单状态
        """
        if order.status in [order.Submitted, order.Accepted]:
            # 如订单已被处理，则不用做任何事情
            return

        # 检查订单是否完成
        if order.status in [order.Completed]:
            if order.isbuy():
                self.buyprice = order.executed.price
                self.buycomm = order.executed.comm
                # print('BUY成交, 执行价={0}, {1}'.format(order.executed.price, order.executed.size))
            # elif order.issell():
            # print('SELL成交, 执行价={0}, {1}'.format(order.executed.price, order.executed.size))
            self.bar_executed = len(self)



        # 订单因为缺少资金之类的原因被拒绝执行
        elif order.status in [order.Canceled, order.Margin, order.Rejected]:
            self.log('Order Canceled/Margin/Rejected')

        # 订单状态处理完成，设为空
        self.order = None

    def notify_trade(self, trade):
        """
        交易成果

        Arguments:
            trade {object} -- 交易状态
        """
        if not trade.isclosed:
            return

        # 显示交易的毛利率和净利润
        self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' %
                 (trade.pnl, trade.pnlcomm), doprint=True)

    def next(self):

        for data in self.datas:
          # 获取仓位
          pos = self.getposition(data).size
          if not pos:

                if    data.sma2[-1]>data.close[-1] and data.close[-1]>data.open[-1] \
                     and data.sma2[-6] > data.sma2[-5] and data.sma2[-5] > data.sma2[-4]and data.sma2[-4] > data.sma2[-3] and data.sma2[-3] > data.sma2[-2] \
                     and data.sma2[-2] > data.sma2[-1] and data.high[-2] > data.high[-1] and data.close[0] > data.close[-1] and data.close[0]>data.open[0]:
                       print(data._name, '', data.datetime.date(0))






                #pctChg =abs( (data.close[-1]-data.open[-1])/data.close[-1]) *100
                #  data.wave[0] > 50 and
                #if data.wave[0] >50 and data.high[0] < data.high[-1] and data.J[0] > data.J[-1] and data.J[0] < data.K[0] and data.K[0] < data.D[0] and data.high[0] < data.sma2[0] and data.open[0] < data.sma2[0] \
                #        and data.high[-2] > data.high[-1] and data.high[-1] > data.high[0]:


                #if data.J[0]< data.K[0] and data.k[0]< data.D[0] and data.high[-3] < data.high[-4] and data.high[-2] > data.high[-3] \
                #        and data.high[-1] > data.high[-2] and data.high[0] > data.high[-1]\
                #        and data.close[-3] < data.sma3[-3] and data.open[-3] < data.sma3[-3] :
                    #if self.getFrontB(data,2,20)==False and self.getFrontB(data,2,10):
                       #print(data.wave[0])
                       self.buy(data=data)
                       data.loss = data.close[-4]
                       # self.order = self.close(exectype=bt.Order.StopTrail, trailpercent=0.1)
          if pos != 0:

              if data.close[0] < data.loss:
                  self.close(data=data)
                  data.loss=0
              else :
                  data.loss = data.close[-4]



              #if data.profit == 1:
              #    self.close(data=data)
                  # print(data._name, '', data.datetime.date(0))
              #    data.profit = 0
                  '''
            if not pos:

                pctChg =abs( (data.close[-1]-data.open[-1])/data.close[-1]) *100
                if pctChg > 3 and pctChg < 6 and data.close[-1] < data.open[-1] and data.high[-1] > data.sma30[-1] and  data.low[-1] < data.sma30[-1] :

                    if self.getFrontB(data,2,20)==False and self.getFrontB(data,2,10):
                       self.buy(data=data)
                       # self.order = self.close(exectype=bt.Order.StopTrail, trailpercent=0.1)
            if pos != 0:
                #pctChg3 = abs((data.close[-4] - data.open[-4]) / data.close[-4]) * 100
                #if pctChg3 > 3 and pctChg3 < 6 and data.close[-4] < data.open[-4] and data.high[-4] > data.sma30[-4] and  data.low[-4] < data.sma30[-4] :
                if data.close[0] < data.close[-1] and data.close[-1] < data.close[-2]:

                    #if self.getFrontB(data,5,23)==False and self.getFrontB(data,5,13):
                       self.close(data=data)'''

    def log(self, txt, dt=None, doprint=False):
            dt = dt or self.datas[0].datetime.date(0)
            print(f'{dt.isoformat()},{txt}')

    def getFrontB(self,data,st,end):
        for i in range(st, end):
            if data.low[-i] < data.sma30[-i]:
                return  False
        return True